#!/usr/bin/python

from optparse import OptionParser
import sys, os
import re
import StringIO



"""
log_specified_lines.pl

	specify which lines using the --lines parameter
	These will be printed to the log with date
"""

# add self to search path for testing
if __name__ == '__main__':
    exe_path = os.path.split(os.path.abspath(sys.argv[0]))[0]
    sys.path.append(os.path.abspath(os.path.join(exe_path,"..", "python_modules")))

import general_util
from custom_log import custom_log
from general_util import die_error




parser = OptionParser(version="%prog 1.0")
parser.add_option("-L", "--log_file_name", dest="logfile",
                  metavar="FILE",                       
                  type="string",
                  help="name and path of log file")
parser.add_option("-l", "--lines", dest="lines",
				  type="string", 
                  help="which lines to keep")
parser.add_option("-m", "--module", dest="module",
				  type="string", 
                  help="name of the module to log", default = '')
parser.add_option("-d", "--description", dest="description",
				  type="string", 
                  help="Description header for the log")
parser.add_option("-f", "--filename", dest = "file_name",
                  metavar="FILE", help="Parse specified lines from this file")
parser.add_option("-i", "--indentation", dest = "indent",
				  type="string", 
                  help="Indent each line with this string")
parser.add_option("-q", "--quiet", dest = "quiet",
                  action="store_true", default=False,
                  help="Do not echo to shell but only print to log.")

parser.set_defaults(file_name = "") 
parser.set_defaults(logfile = "") 
parser.set_defaults(lines = "")              
parser.set_defaults(module = "")                         
parser.set_defaults(indent = "    ")                         
parser.set_defaults(description = "")                         

# get help string
f =StringIO.StringIO()
parser.print_help(f)
helpstr = f.getvalue()
(options, args) = parser.parse_args()

if not len(options.file_name):
    die_error("Please specify a file in --file.\n\n"+helpstr)
if (not len(options.lines)):
    die_error("No lines specified in --lines.\n\n"+helpstr)
if (not len(options.module)):
    die_error("No module specified in --module.\n\n"+helpstr)




noted_lines = list();

# 
# make sure the lines parameter is in right format
# 
regex = re.compile(r"^((\d+)\s*(?:\-\s*(\d+))?\s*,\s*)+$");
match = regex.match(options.lines + ",")
if not match:
    die_error("The --lines parameter should contain comma separated values or ranges. [" 
              + options.lines + "]")



def specify_lines_to_keep ():
    noted_lines = list();
    regex = re.compile(r"(\d+)\s*(?:\-\s*(\d+))?\s*,\s*");
    for crange in regex.findall(options.lines + ","):
        range = list(crange)
        if not len(range[1]):
            range[1] = range[0]
        range = [int(x) for x in range]
        if range[1] < range[0]:
            die_error(str(range[0]) + "-" + str(range[1]) + 
                        " is not a valid range of lines")
        for a in xrange(range[0], range[1] + 1):
            noted_lines.append(a - 1)
    return noted_lines
    

# get lines from --lines parameters
noted_lines = specify_lines_to_keep()

# read file and extract lines
# convert tabs to 4 spaces
file_lines = file(options.file_name).readlines()
saved_lines = list();
for line_num in noted_lines:
    if line_num < len(file_lines):
        saved_lines.append(file_lines[line_num].replace('\t', '    '))

# get maximum whitespace on left to use as indent
regex_indent =  re.compile("^( *)")
min_indent = min ([len(regex_indent.search(x).group(0)) for x in saved_lines])

# log
status_log = custom_log(options.module, options.logfile, options.quiet)
status_log.no_new_line_on_exit()
if len(options.description):
    status_log.info(options.description)
for line in saved_lines:
    status_log.info(options.indent + line[min_indent:-1])



